package com.tansun.easycare.rule.ruletest.service.impl;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.kie.api.KieBase;
import org.kie.api.io.ResourceType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tansun.easycare.rule.codeblock.service.RuleCodeblockService;
import com.tansun.easycare.rule.common.enums.ContentTypeEnum;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.common.service.RuleRefCommService;
import com.tansun.easycare.rule.common.service.impl.RuleBaseServiceImpl;
import com.tansun.easycare.rule.datamodel.entity.RuleDataparams;
import com.tansun.easycare.rule.datamodel.service.RuleDataparamsService;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.executionblock.service.ExecutionBlockService;
import com.tansun.easycare.rule.referencedata.entity.RuleReferenceData;
import com.tansun.easycare.rule.referencedata.service.RuleReferenceDataService;
import com.tansun.easycare.rule.ruleflow.service.RuleFlowService;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupService;
import com.tansun.easycare.rule.rulelog.service.RuleLogsService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruletest.dao.RuleTestDao;
import com.tansun.easycare.rule.ruletest.entity.RuleTest;
import com.tansun.easycare.rule.ruletest.entity.RuleTestItem;
import com.tansun.easycare.rule.ruletest.model.RuleBatchResult;
import com.tansun.easycare.rule.ruletest.model.RuleInputVO;
import com.tansun.easycare.rule.ruletest.model.RuleItem;
import com.tansun.easycare.rule.ruletest.model.RuleSingleTest;
import com.tansun.easycare.rule.ruletest.model.RuleTestMap;
import com.tansun.easycare.rule.ruletest.model.RuleTestVO;
import com.tansun.easycare.rule.ruletest.model.TestDataModeVO;
import com.tansun.easycare.rule.ruletest.model.TestDatasetVO;
import com.tansun.easycare.rule.ruletest.service.RuleTestItemService;
import com.tansun.easycare.rule.ruletest.service.RuleTestService;
import com.tansun.easycare.rule.ruleversion.entity.RuleVersioninfo;
import com.tansun.easycare.rule.ruleversion.service.RuleVersioninfoService;
import com.tansun.easycare.rule.utils.DroolsExcuteDrlUtils;
import com.tansun.rule.common.KieBaseFactory;
import com.tansun.rule.common.ResourceContentInfo;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.DroolsRuleLog;
import com.tansun.rule.utils.LoggerManager;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.MField;
import com.tansun.rule.utils.RuleBomMapJsonConvert;
import com.tansun.rule.utils.RuleBomMapXmlConvert;
import com.tansun.rule.utils.StringUtils;
import com.tansun.ruledata.data.service.RuleResourceLoadService;

import lombok.Data;

@Service
public class RuleTestServiceImpl extends RuleBaseServiceImpl<RuleTestDao, RuleTest> implements RuleTestService {

	@Autowired
	private  RuleManageService  ruleManageService;

    @Autowired
    private RuleReferenceDataService ruleReferenceDataService;

    @Autowired
    private RuleTestItemService ruleTestItemService;

    @Autowired
    private DataBomService dataBomService;

    @Autowired
    private RuleVersioninfoService ruleVersioninfoService;

    @Autowired
    private ExecutionBlockService executionBlockService;

    @Autowired
    private RuleFlowService ruleFlowService;

    @Autowired
    private RuleRefCommService ruleRefCommService;

    @Autowired
    private RuleCodeblockService ruleCodeblockService;
    @Autowired
    private RuleGroupService ruleGroupService;
    @Autowired
    RuleResourceLoadService ruleResourceLoadService;
	@Autowired
	private  RuleDataparamsService  ruleDataparamsService;

    static final SimpleDateFormat spf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    //批量测试一次性测试数据数量，根据内存调整
    public static final int EXR_DROOL_EXR_RPE_SIZE = 5000;

    private static final int MAX_DROOL_EXR_RPE_SIZE = 5000;

    @Override
    public TestDataModeVO findDataModeVO(String projectCode, String code, String type, String version) throws BizException {
        if (RuleModelTypeEnum.ExecutionBlock.code.equals(type)) {
            List<RuleReferenceData> list = ruleRefCommService.findExcBlockRefData(projectCode, code, version);
            return this.findBaseDataModeVO(projectCode, code, type, version, this.ruleReferenceDataService.reDataModeRef(list));
        } else if (RuleModelTypeEnum.RuleFlow.code.equals(type) || RuleModelTypeEnum.StrategyFlow.code.equals(type)) {
            List<RuleReferenceData> list = this.ruleRefCommService.findRuleFlowReferenceData(projectCode, code, version, null);
//            List<String> strList =this.ruleFlowService.findRuleFlowRefeList(projectCode, code, version);
//            if (strList !=null && strList.size()>0) {
//            	Map<String,Object>  oMap  = new  HashMap<>();
//            	oMap.put("projectCode", projectCode);
//            	oMap.put("refeList", strList);
//            	List<RuleReferenceData> rdList =this.ruleReferenceDataService.findModelReferenceList(oMap);
//            	list.addAll(rdList);
//            }
            return this.findBaseDataModeVO(projectCode, code, type, version, this.ruleReferenceDataService.reDataModeRef(list));
        } else {
            return this.findBaseDataModeVO(projectCode, code, type, version, null);
        }
    }

    private TestDataModeVO findBaseDataModeVO(String projectCode, String code, String type, String version, Collection<RuleReferenceData> refList) throws BizException {
        TestDataModeVO dataModeVO = new TestDataModeVO();
        Collection<RuleReferenceData> list;
        if (refList == null) {
        	list = new ArrayList<RuleReferenceData>();
            this.ruleReferenceDataService.findReferenceDataList(projectCode,code,type,version,null,list,null);
        } else {
            list = refList;
        }
		RuleManage ruleInfo = new RuleManage();
		ruleInfo.setCode(code);
		ruleInfo.setVersion(version);
		ruleInfo.setModelType(type);
		ruleInfo.setProjectCode(projectCode);
		List<RuleManage> rmlist =this.ruleManageService.findList(ruleInfo);
		if (rmlist == null || rmlist.size()==0){
			throw  new  BizException("E-000600");
		}
		ruleInfo = rmlist.get(0);
        ruleReferenceDataService.findFuncReferenceDataList(ruleInfo, list);
        RuleItem testItem = null;
        Map<String, TestDatasetVO> inputMap = new HashMap();
        Map<String, TestDatasetVO> thenMap = new HashMap();
        TestDatasetVO inputDatasetVO = null;
        TestDatasetVO thenDatasetVO = null;
        Map<String, RuleItem> rtMap = new HashMap();
        for (RuleReferenceData tmpData : list) {
            testItem = rtMap.get(tmpData.getClassName() + "." + tmpData.getNameen() + tmpData.getContentType());
            if (testItem != null)
                continue;
            testItem = new RuleItem();
            try {
            	ConvertUtils.register(new DateConverter(null), java.util.Date.class);
                BeanUtils.copyProperties(testItem, tmpData);
                testItem.setItemType(tmpData.getContentType());
                if("func".equals(testItem.getDataType())) {
                	RuleDataparams search = new RuleDataparams();
                	search.setChzn(testItem.getNamecn());
                	search.setName(testItem.getNameen());
                	search.setProjectcode(tmpData.getProjectCode());
                	List<RuleDataparams> paramsList = ruleDataparamsService.findList(search);
                	if(!paramsList.isEmpty()) {
                		testItem.setDataType(paramsList.get(0).getType());
                	}
                }

                rtMap.put(testItem.getClassName() + "." + testItem.getNameen() + tmpData.getContentType(), testItem);
            } catch (Exception e) {
                throw new BizException(e, "");
            }
            if (ContentTypeEnum.in.code.equals(tmpData.getContentType())) {
                inputDatasetVO = inputMap.get(tmpData.getClassName());
                if (inputDatasetVO == null) {
                    inputDatasetVO = new TestDatasetVO();
                    inputDatasetVO.setChzn(tmpData.getClassNamecn());
                    inputDatasetVO.setName(tmpData.getClassName());
                    inputMap.put(tmpData.getClassName(), inputDatasetVO);
                    dataModeVO.getInputDataModel().add(inputDatasetVO);
                }

                inputDatasetVO.getAttrList().add(testItem);
                //dataModeVO.getInputDataModel().add(testItem);
            } else {
                thenDatasetVO = thenMap.get(tmpData.getClassName());
                if (thenDatasetVO == null) {
                    thenDatasetVO = new TestDatasetVO();
                    thenDatasetVO.setChzn(tmpData.getClassNamecn());
                    thenDatasetVO.setName(tmpData.getClassName());
                    thenMap.put(tmpData.getClassName(), thenDatasetVO);
                    dataModeVO.getThenDataModel().add(thenDatasetVO);
                }

                thenDatasetVO.getAttrList().add(testItem);

                //dataModeVO.getThenDataModel().add(testItem);
            }

        }
        if(RuleModelTypeEnum.GeneralRule.code.equals(type)) {
        	generalRuleAddReasonScore(ruleInfo, dataModeVO,thenMap);
        }
        if(dataModeVO.getInputDataModel()!=null) {
            for(TestDatasetVO testDatasetVO :dataModeVO.getInputDataModel()) {
            	Collections.sort(testDatasetVO.getAttrList());
            }
        }
        return dataModeVO;

    }
    /**
     * 普通规则添加原因代码及分数
     * @param ruleManage
     * @param dataModeVO
     */
    private void generalRuleAddReasonScore(RuleManage ruleManage,TestDataModeVO dataModeVO, Map<String, TestDatasetVO> thenMap) {
    	TestDatasetVO ruleVO = thenMap.get(ruleManage.getCode());
        if (ruleVO == null) {
        	ruleVO = new TestDatasetVO();
        	ruleVO.setChzn(ruleManage.getName());
        	ruleVO.setName(ruleManage.getCode());
            dataModeVO.getThenDataModel().add(ruleVO);
        }

        String testId = "";
        try {
        	testId = dataModeVO.getThenDataModel().get(0).getAttrList().get(0).getTestId();
        }catch(Exception e){}

        RuleItem ruleReason = new RuleItem();
        ruleReason.setClassName(ruleManage.getCode());
        ruleReason.setClassNamecn(ruleManage.getName());
        ruleReason.setDataType("String");
        ruleReason.setDefaultValue("");
        ruleReason.setTestId(testId);
        ruleReason.setIsCollections("false");
        ruleReason.setIsDerives("false");
        ruleReason.setNamecn("原因代码");
        ruleReason.setNameen("reasonList");
        ruleReason.setCollection("");
        ruleReason.setItemType(ContentTypeEnum.out.code);
        ruleVO.getAttrList().add(ruleReason);

        RuleItem ruleScore = new RuleItem();
        ruleScore.setClassName(ruleManage.getCode());
        ruleScore.setClassNamecn(ruleManage.getName());
        ruleScore.setDataType("Double");
        ruleScore.setDefaultValue("0");
        ruleScore.setTestId(testId);
        ruleScore.setIsCollections("false");
        ruleScore.setIsDerives("false");
        ruleScore.setNamecn("规则总分");
        ruleScore.setDomain("[0,9999999]");
        ruleScore.setNameen("ruleScoreSum");
        ruleScore.setCollection("");
        ruleScore.setItemType(ContentTypeEnum.out.code);
        ruleVO.getAttrList().add(ruleScore);

    }
    @Override
    public RuleTest saveOrUpdate(RuleTestVO ruleTest) throws BizException {
        RuleTest rTest = new RuleTest();
        if (StringUtils.isEmpty(ruleTest.getId())) {
            this.makeRuleTest(ruleTest, rTest);
            rTest.setStatus("0");
            rTest.setTestType("0");
            this.save(rTest);
            ruleTest.getRuleTestItem().setTestId(rTest.getId());
            ruleTestItemService.save( ruleTest.getRuleTestItem());;
        }else {
        	 this.makeRuleTest(ruleTest, rTest);
        	 rTest.setId(ruleTest.getId());
             rTest.setStatus("0");
             rTest.setTestType("0");
             this.save(rTest);
             RuleTestItem queryTestItem = new  RuleTestItem();
             queryTestItem.setTestId(ruleTest.getId());
             List<RuleTestItem> list = ruleTestItemService.findList(queryTestItem);
             if (list !=null && list.size()>0) {
            	 ruleTest.getRuleTestItem().setId(list.get(0).getId());
             }
             ruleTest.getRuleTestItem().setTestId(rTest.getId());
             ruleTestItemService.save( ruleTest.getRuleTestItem());
        }
        return rTest;
    }


    private void makeRuleTest(RuleTestVO vo, RuleTest bo) {
        bo.setTestName(vo.getName());
        bo.setModelCode(vo.getRuleCode());
        bo.setModelType(vo.getType());
        bo.setFormatType(vo.getFormatType());
        bo.setProjectCode(vo.getProjectCode());
        bo.setVersion(vo.getVersion());
        bo.setTracks(vo.getTracks());
    }

    private void makeRuleItem(List<RuleTestItem> list, List<RuleItem> rList, String type, String parentId) {
        if (list == null || list.size() == 0)
            return;
        RuleTestItem ruleTestItem = null;
        String key = "";
        String[] keyArgs = null;


    }

    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Map<String, Object> testRule(RuleTestMap testInfo, Map<String, Object> inputMap,String championInfo,List<Map<String,Object>> inputPram) throws BizException {
        if (inputPram != null) {

        	for (Map<String,Object> parMap:inputPram) {
        		 String key  =(String)parMap.get("key");
        		 String[] strArgs = StringUtils.split(key, ".");
        		 Map<String,Object> vMap  = new  HashMap<>();
        		 Object val = parMap.get("value");
        		 if (inputMap == null) {
        			 inputMap= new  HashMap<>();
        		 }
        		 Object  obj  = inputMap.get(strArgs[0]);
        		 if (obj !=null) {
        			 Map<String,Object> inpMap =   (Map<String, Object>) obj;
        			 inpMap.put(strArgs[1], val);
        		 }else {
        	  		 vMap.put(strArgs[1], val);
        	  		 inputMap.put(strArgs[0], vMap);
        		 }
        	}
        	//inputMap.putAll(inMap);
        }
        if(inputMap!=null) {
        	for(String key:inputMap.keySet()) {
        		Map<String,Object> chmap = (Map)inputMap.get(key);
        		if(chmap!=null) {
        			for(String chkey:chmap.keySet()) {
        				Object obj = chmap.get(chkey);
        				if(obj instanceof List) {
        					List<Object> listObj = (List)obj;
        					List<Object> listObj1 = new ArrayList<>();
        					if(listObj!=null) {
	        					for(Object o:listObj) {
	        						Map<String,Object> valMap = (Map)o;
	        						listObj1.add(valMap.get("value"));
	        					}
	        					chmap.put(chkey, listObj1);
        					}else {
        						chmap.put(chkey, listObj1);
        					}
        				}else if( obj instanceof String && obj!=null) {
        					obj = obj.toString().trim();
        					chmap.put(chkey, obj);
        				}
        			}
        		}
        	}
        }
    	Map<String, MClass> metaMap = this.dataBomService.findMapClass(testInfo.getProjectCode());
        RuleBomMapXmlConvert bomMapConvert = new RuleBomMapXmlConvert();
        Map<String, Object> insertMap = bomMapConvert.buildMap(metaMap, true);
        // 数组存在问题
        Map<String, Object> inputMapTemp = new HashMap<String, Object>();
        if (inputMap != null) {
            inputMapTemp.putAll(inputMap);
            for (Map.Entry entry : inputMap.entrySet()) {
                Map<String, Object> map_temp = new HashMap<String, Object>();
                map_temp.putAll((Map<String, Object>) entry.getValue());
                Map<String, Object> insertMapM = (Map<String, Object>) insertMap.get(entry.getKey());
                if (insertMapM == null) {
                    continue;
                }
                for (Map.Entry e : map_temp.entrySet()) {
                    if (insertMapM.get(e.getKey()) instanceof ArrayList) {
                        Object s =  e.getValue();
                        if(s == null ) continue;
                        List<String> listT = new ArrayList<String>();
                        if (s instanceof ArrayList<?>) {
                        	List<?> aList = (List)s;
                        	for (Object obj:aList) {
                        		try {
                        			listT.add((String) PropertyUtils.getProperty(obj, "value"));
								} catch (Exception e1) {
									throw new BizException(e1, "");
								}
                        	}
                        }
//                        String[] newstr = s.split(",");
//                        for (int i = 0; i < newstr.length; i++) {
//                            listT.add(newstr[i]);
//                        }
                        Map<String, Object> inputMap_attr = (Map<String, Object>) inputMap.get(entry.getKey());
                        inputMap_attr.remove(e.getKey());
                        inputMap_attr.put((String) e.getKey(), (Object) listT);// 关键
                        inputMapTemp.remove(entry.getKey());
                        inputMapTemp.put((String) entry.getKey(), (Object) inputMap_attr);
                    }
                }
            }
        }
        try {
//        String xml = RuleBomMapXmlConvert.bom2xml(inputMapTemp, metaMap, true);
        	//判断传进参数，并进行响应匹配
        		Map<String, String> championParam = new HashMap<>();
            	if("champion".equals(championInfo)) {
            		championParam.put("champion", "true");
                	inputMapTemp.put("championInfo", championParam);
            	}else {
            		championParam.put("challenger", championInfo);
            		inputMapTemp.put("championInfo", championParam);
            	}
	        String inputJson = RuleBomMapJsonConvert.bom2Json(inputMapTemp, metaMap);
	        insertMap = RuleBomMapJsonConvert.json2bom(inputJson, metaMap,true);
	        DroolsExcuteDrlUtils dedu = new DroolsExcuteDrlUtils();
	        dedu.setProjectCode(testInfo.getProjectCode());
	        Map<String,String> rrMap  = new  HashMap<>();
	        rrMap.put(testInfo.getProjectCode(),this.ruleCodeblockService.getEffectiveFunc(testInfo.getProjectCode()));

	        dedu.setFuncMap(rrMap);
	        String modelType = testInfo.getType();
            if (RuleModelTypeEnum.DecisionTree.code.equals(modelType)
            		|| RuleModelTypeEnum.RuleFlow.code.equals(modelType)
            		|| RuleModelTypeEnum.StrategyFlow.code.equals(modelType)
            		|| RuleModelTypeEnum.ExecutionBlock.code.equals(modelType)) {
            	dedu.setDrlMap(this.ruleVersioninfoService.findProjectRefeVersion(testInfo.getProjectCode()));
            }
	        bomMapConvert.doDerives(insertMap, metaMap);

	        if (RuleModelTypeEnum.RuleFlow.code.equals(modelType) || RuleModelTypeEnum.StrategyFlow.code.equals(modelType) ) {//规则流执行
	            List<RuleVersioninfo> vList = this.ruleFlowService.findRuleFlowPublishVersion(testInfo.getProjectCode(), testInfo.getCode(), testInfo.getVersion());
	            ruleCodeblockService.addFuncInfo(vList);
//                dedu.executeDrlContents(insertMap, vList, metaMap, testInfo.getCode() + "_" + testInfo.getVersion());
	            ruleResourceLoadService.loadProjectPmml(testInfo.getProjectCode());
	            ruleResourceLoadService.loadProjectPmmlRefData(testInfo.getProjectCode());
                dedu.executeDrlContents(insertMap, vList, metaMap, testInfo.getCode());
                insertMap.put("tracks",getTrailMap(dedu.getDroolsRuleLog()));
	        } else if (RuleModelTypeEnum.ExecutionBlock.code.equals(modelType)) {//执行快
	            List<RuleVersioninfo> vList = this.executionBlockService.findRuleRefVersion(testInfo.getProjectCode(), testInfo.getCode(), testInfo.getVersion());
	            ruleCodeblockService.addFuncInfo(vList);
//                dedu.executeDrlContents(insertMap, vList, metaMap, testInfo.getCode() + "_" + testInfo.getVersion());
                dedu.executeDrlContents(insertMap, vList, metaMap, testInfo.getCode());
                insertMap.put("tracks",getTrailMap(dedu.getDroolsRuleLog()));
    	    } else if(RuleModelTypeEnum.CodeBlock.code.equals(modelType)) {
              String agendaGroup = testInfo.getCode();
              Map<String, Object> map = new HashMap();
              map.put("code", testInfo.getCode());
              map.put("projectCode", testInfo.getProjectCode());
              map.put("version", testInfo.getVersion());
              List<RuleVersioninfo> vList = this.ruleVersioninfoService.findVersionList(map);
              if(vList!=null && !vList.isEmpty()) {
            	  RuleVersioninfo versionInfo = vList.get(vList.size()-1);
	              String funcDrl = ruleCodeblockService.genDrl(testInfo.getProjectCode());
	              dedu.excuteDrl(insertMap, new String[]{funcDrl}, metaMap, agendaGroup, new String[] {versionInfo.getRuleContent()});
	              insertMap.put("tracks",getTrailMap(dedu.getDroolsRuleLog()));
              }else {
            	  throw new BizException("未找到对应版本数据");
              }
//	        }else if(RuleModelTypeEnum.GeneralRule.code.equals(modelType)) {
//                String agendaGroup = testInfo.getCode();
//
//                RuleManage ruleManage = new RuleManage();
//                ruleManage.setCode(agendaGroup);
//                ruleManage.setProjectCode(testInfo.getProjectCode());
//                ruleManage.setVersion(testInfo.getVersion());
//
//                String ruleDrl = this.ruleGroupService.getRuleDrl(ruleManage);
//                String funcDrl = ruleCodeblockService.genDrl(testInfo.getProjectCode());
//                dedu.excuteDrl(insertMap, new String[]{funcDrl, ruleDrl}, metaMap, agendaGroup, null);
//                insertMap.put("tracks",getTrailMap(dedu.getDroolsRuleLog()));
	        } else {//单个drl文件
//                String agendaGroup = testInfo.getCode() + "_" + testInfo.getVersion();
                String agendaGroup = testInfo.getCode();
                Map<String, Object> map = new HashMap();
                map.put("code", testInfo.getCode());
                map.put("projectCode", testInfo.getProjectCode());
                map.put("version", testInfo.getVersion());
                List<RuleVersioninfo> vList = this.ruleVersioninfoService.findVersionList(map);
                //ruleCodeblockService.addFuncInfo(vList);
                if (vList != null && vList.size() > 0) {
                    String ruleDrl = vList.get(vList.size()-1).getRuleContent();
                    String funcDrl = rrMap.get(testInfo.getProjectCode());
                    dedu.excuteDrl(insertMap, new String[]{funcDrl, ruleDrl}, metaMap, agendaGroup, null);
//                    if (RuleModelTypeEnum.PolicyRuleGroup.code.equals(modelType)) {
//                        String funcDrl = ruleCodeblockService.genDrl(testInfo.getProjectCode());
//                        dedu.excuteDrl(insertMap, new String[]{funcDrl, ruleDrl}, metaMap, agendaGroup, null);
//                    } else {
//                        dedu.excuteDrlFile(insertMap, ruleDrl, metaMap, agendaGroup);
//                    }
                    insertMap.put("tracks",getTrailMap(dedu.getDroolsRuleLog()));
                }
	        }
	        insertMap = dedu.getDroolsRuleLog().getScoreTrailMap(insertMap);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(e, "");
        }
        Set<String> keys = insertMap.keySet();
        for (String key : keys) {
            MClass dClass = metaMap.get(key);
            if(dClass==null)
            	continue;
            Map<String, MField> mFields = dClass.getFieldMap();
            Object obj = insertMap.get(key);
            if (obj instanceof Map) {
                Map<String, Object> iMap = (Map) obj;
                for (String tKey : iMap.keySet()) {
                    MField mFiled = mFields.get(tKey);
                    if (mFiled != null && mFiled.getType().equals("Date")) {
                        Object tObj = iMap.get(tKey);
                        if (tObj instanceof Date) {
                            SimpleDateFormat dateFormat = new SimpleDateFormat(mFiled.getPattern());
                            iMap.put(tKey, dateFormat.format(tObj));
                        }

                    }
                }
            }
        }
        doRuleResultDoubleParse(insertMap,metaMap);
        return insertMap;
    }
    public void doRuleResultDoubleParse(Map<String, Object> insertMap,Map<String, MClass> metaMap) {
    	if(insertMap==null) {
    		return;
    	}
    	DecimalFormat dFormat = new DecimalFormat("0.000000");
    	for(Entry<String, Object> entry:insertMap.entrySet()) {
    		MClass mClass = metaMap.get(entry.getKey());
    		if(mClass!=null) {
        		Map<String,Object> params = (Map<String, Object>) entry.getValue();
        		for(Entry<String, Object> param:params.entrySet()) {
        			MField mField = mClass.getFieldMap().get(param.getKey());
        			if(mField!=null) {
	        			if("Double".equalsIgnoreCase(mField.getType())) {
	//        				params.put(param.getKey(),StringUtils.rvZeroAndDot(dFormat.format(param.getValue())));
	        			}
        			}
        		}
    		}
    	}
    }
//    @Autowired
//    RuleDataBusinessService ruleDataBusinessService;
    @SuppressWarnings({"rawtypes", "unchecked"})
    public RuleBatchResult testBatchRule(RuleTestMap testInfo, List<Map<String, Object>> inputMaps) throws BizException {
    	RuleBatchResult  ruleBatchResult  = new  RuleBatchResult();
        Map<String, MClass> metaMap = this.dataBomService.findMapClass(testInfo.getProjectCode());
        RuleBomMapXmlConvert bomMapConvert = new RuleBomMapXmlConvert();
        Map<String, Object> insertMap = bomMapConvert.buildMap(metaMap, true);
//        List<Map<String, Object>> insertMaps = new ArrayList<Map<String, Object>>();
        // 数组存在问题
//        for (Map<String, Object> inputMap : inputMaps) {
//
//            Map<String, Object> inputMapTemp = new HashMap<String, Object>();
//            inputMapTemp.putAll(inputMap);
//            for (Map.Entry entry : inputMap.entrySet()) {
//                Map<String, Object> map_temp = new HashMap<String, Object>();
//                map_temp.putAll((Map<String, Object>) entry.getValue());
//                Map<String, Object> insertMapM = (Map<String, Object>) insertMap.get(entry.getKey());
//                if(insertMapM==null)	continue;
//                for (Map.Entry e : map_temp.entrySet()) {
//                    if (insertMapM.get(e.getKey()) instanceof ArrayList ) {
//                    	if(e.getValue()==null){
//                    		continue;
//                    	}
//                        String s = e.getValue().toString();
//                        List<String> listT = new ArrayList<String>();
//                        if(StringUtils.isNotEmpty(s)) {  //by wangyanghui,2019.01.03.去除list为空（list为String类型，会出现空串）时，赋空值的错误。
//
//                        	String[] newstr = s.split(",");
//                        	for (int i = 0; i < newstr.length; i++) {
//                        		listT.add(newstr[i]);
//
//                        	}
//                        }
//                        Map<String, Object> inputMap_attr = (Map<String, Object>) inputMap.get(entry.getKey());
//                        inputMap_attr.remove(e.getKey());
//                        inputMap_attr.put((String) e.getKey(), (Object) listT);// 关键
//                        inputMapTemp.remove(entry.getKey());
//                        inputMapTemp.put((String) entry.getKey(), (Object) inputMap_attr);
//                        // ((List<String>)((Map<String,Object>)inputMap.get(entry.getKey())).get(e.getKey())).addAll(listT);
//                     }
//
//                }
//            }
//            try {
//            	Map tmp= RuleBomMapXmlConvert.xml2bom(RuleBomMapXmlConvert.bom2xml(inputMapTemp, metaMap, true), metaMap, true);
////            	tmp = ruleDataBusinessService.initRuleParam_platform(testInfo.getProjectCode(), testInfo.getCode(), testInfo.getVersion(), metaMap,tmp);
//
//                insertMaps.add(tmp);
//            } catch (Exception e) {
//            	e.printStackTrace();
//                throw new BizException(e, "");
//            }
//        }

        DroolsExcuteDrlUtils dedf = new DroolsExcuteDrlUtils();
        dedf.setProjectCode(testInfo.getProjectCode());
        Map<String,String> funcMap  = new  HashMap<>();
        funcMap.put(testInfo.getProjectCode(),this.ruleCodeblockService.getEffectiveFunc(testInfo.getProjectCode()));
        dedf.setFuncMap(funcMap);
        dedf.setDrlMap(this.ruleVersioninfoService.findProjectRefeVersion(testInfo.getProjectCode()));
//		Collection<File> files=null;
        List<ResourceContentInfo> drlList = new ArrayList<>();
        ResourceContentInfo  resContent = null;
        if (RuleModelTypeEnum.StrategyFlow.code.equals(testInfo.getType())
        		|| RuleModelTypeEnum.RuleFlow.code.equals(testInfo.getType())) {
            List<RuleVersioninfo> vList = this.ruleFlowService.findRuleFlowPublishVersion(testInfo.getProjectCode(), testInfo.getCode(), testInfo.getVersion());
//            ruleCodeblockService.addFuncInfo(vList);
            // 批量处理

            for (RuleVersioninfo versioninfo : vList) {
                if (RuleModelTypeEnum.RuleFlow.code.equals(versioninfo.getModelType()) ||
                		RuleModelTypeEnum.StrategyFlow.code.equals(versioninfo.getModelType()) ||
                        RuleModelTypeEnum.ExecutionBlock.code.equals(versioninfo.getModelType())) {
                    try {
                    	resContent = new  ResourceContentInfo(versioninfo.getRuleContent(), ResourceType.BPMN2);
                        drlList.add(resContent);
                    } catch (Exception e) {
                        throw new BizException(e, "");
                    }
                } else {
                    try {
                    	if(!RuleModelTypeEnum.DataMining.code.equals(versioninfo.getModelType()) ) {
                    		resContent = new  ResourceContentInfo(versioninfo.getRuleContent(), ResourceType.DRL);
                    		drlList.add(resContent);
                    	}
                    } catch (Exception e) {
                        throw new BizException(e, "");
                    }
                }
            }

        } else if (RuleModelTypeEnum.ExecutionBlock.code.equals(testInfo.getType())) {
            List<RuleVersioninfo> vList = this.executionBlockService.findRuleRefVersion(testInfo.getProjectCode(), testInfo.getCode(), testInfo.getVersion());
            for (RuleVersioninfo versioninfo : vList) {
                if (RuleModelTypeEnum.ExecutionBlock.code.equals(versioninfo.getModelType())) {
                    try {
                    	resContent = new  ResourceContentInfo(versioninfo.getRuleContent(), ResourceType.BPMN2);
                        drlList.add(resContent);
                    } catch (Exception e) {
                        throw new BizException(e, "");
                    }
                } else {
                    try {
                    	resContent = new  ResourceContentInfo(versioninfo.getRuleContent(), ResourceType.DRL);
                        drlList.add(resContent);
                    } catch (Exception e) {
                        throw new BizException(e, "");
                    }
                }
            }

        } else {
            Map<String, Object> map = new HashMap();
            map.put("code", testInfo.getCode());
            map.put("projectCode", testInfo.getProjectCode());
            map.put("version", testInfo.getVersion());
            List<RuleVersioninfo> list = this.ruleVersioninfoService.findVersionList(map);
            if (list != null && list.size() > 0) {
                try {
                	resContent = new  ResourceContentInfo(list.get(0).getRuleContent(), ResourceType.DRL);
                    drlList.add(resContent);
                } catch (Exception e) {
                    throw new BizException(e, "");
                }
            }
        }
        RuleSingleTest 	ruleSingleTest = new RuleSingleTest();
        RuleInputVO  inputVO  = null;
        for ( Map<String, Object> inputMap:inputMaps) {
        	inputVO  = new  RuleInputVO();
        	inputVO.setInputMaps(inputMap);
        	ruleSingleTest.getInputList().add(inputVO);

        }
        System.out.println("#################"+inputMaps.size()+"开始执行");
        Date  d  = new  Date();
        KieBase  kieBase  = null;
        if (testInfo.getType().equals(RuleModelTypeEnum.RuleFlow.code)
        		|| testInfo.getType().equals(RuleModelTypeEnum.StrategyFlow.code)) {
            // 批量处理
            ruleResourceLoadService.loadProjectPmml(testInfo.getProjectCode());
            ruleResourceLoadService.loadProjectPmmlRefData(testInfo.getProjectCode());
        }
        try {
			kieBase= KieBaseFactory.getInstance().createKieBase(drlList);
		} catch (Exception e) {
			throw  new  BizException(e, "");
		}
        ForkJoinPool mainPool = new ForkJoinPool();

        SubTask task = new SubTask(ruleSingleTest, 0, inputMaps.size(), metaMap, testInfo,kieBase,dedf);
        mainPool.invoke(task);
        Date  ed = new Date();
        ruleBatchResult.setExecuteDateTime(ed.getTime() - d.getTime());
        ruleBatchResult.setRuleSingleTest(ruleSingleTest);
        System.out.println("#################"+inputMaps.size()+"执行完成"+";执行时间：="+ruleBatchResult.getExecuteDateTime());
//        inputMaps=insertMaps;
        return ruleBatchResult;
    }
    @Override
    public RuleTestVO findRuleTestVO(String id) throws BizException {
        RuleTest ruleTest = this.dao.get(id);
        RuleTestVO ruleTestVO = new RuleTestVO();
        ruleTestVO.setId(ruleTest.getId());
        ruleTestVO.setName(ruleTest.getTestName());
        ruleTestVO.setRuleCode(ruleTest.getModelCode());
        ruleTestVO.setVersion(ruleTest.getVersion());
        ruleTestVO.setType(ruleTest.getModelType());
        ruleTestVO.setTracks(ruleTest.getTracks());
        ruleTestVO.setFormatType(ruleTest.getFormatType());
        RuleTestItem testItem = new RuleTestItem();
        testItem.setTestId(id);
        List<RuleTestItem> list = this.ruleTestItemService.findList(testItem);
        if (list !=null && list.size()>0) {
        	RuleTestItem RuleTestItem = list.get(0);
        	ruleTestVO.setRuleTestItem(RuleTestItem);
        }
        return ruleTestVO;
    }
    @Autowired
    RuleLogsService ruleLogsService;

    @Override
    public void delRuleTest(String id) throws BizException {
        Map<String, Object> map = new HashMap();
        map.put("testId", id);
        this.ruleTestItemService.deleteByTestId(map);
        this.dao.delete(new RuleTest(id));
    }


    //多线程
    class SubTask extends RecursiveAction {

        private static final long serialVersionUID = 1L;

        private RuleSingleTest inputMaps;
        private int beg;
        private int end;

        private RuleTestMap ruleTest;

        private  KieBase  kieBase;

        Map<String, MClass> metaMap;



        private DroolsExcuteDrlUtils dedf;

        public SubTask(RuleSingleTest inputMaps, int beg, int end, Map<String, MClass> metaMap, RuleTestMap ruleTest,KieBase  kieBase , DroolsExcuteDrlUtils dedf) {
            super();
            this.inputMaps = inputMaps;
            this.beg = beg;
            this.end = end;
            this.kieBase  = kieBase;
            this.ruleTest = ruleTest;
            this.metaMap = metaMap;

            this.dedf = dedf;
        }

        @Override
        protected void compute() {
//            String agendaGroup = ruleTest.getCode() + "_" + ruleTest.getVersion();
        	String agendaGroup = ruleTest.getCode();
            if (end - beg > RuleTestServiceImpl.EXR_DROOL_EXR_RPE_SIZE) {
                int mid = (beg + end) / 2;
                SubTask t1 = new SubTask(inputMaps, beg, mid, metaMap, ruleTest, kieBase, dedf);
                SubTask t2 = new SubTask(inputMaps, mid, end, metaMap, ruleTest, kieBase, dedf);
                invokeAll(t1, t2);
            } else {
                try {
                    System.out.println("###############第" + beg + "至" + end + "线程进入时间:" + RuleTestServiceImpl.spf.format(new Date()) + "#################");
                    if (ruleTest.getType().equals(RuleModelTypeEnum.RuleFlow.code)
                    	|| ruleTest.getType().equals(RuleModelTypeEnum.StrategyFlow.code)	) {
                        // 批量处理
                        dedf.excuteBatchDrl(inputMaps.getInputList().subList(beg, end), metaMap, agendaGroup,kieBase,true);
                    } else {
                        dedf.excuteDrlFile(inputMaps.getInputList().subList(beg, end),  metaMap, agendaGroup,kieBase);
                    }
                    System.out.println("###############第" + beg + "至" + end + "线程结束时间:" + RuleTestServiceImpl.spf.format(new Date()) + "#################");
                } catch (Exception e) {
                    LoggerManager.error("", e, this.getClass());
                }
            }
        }
    }

    public List<String> getTrackId(DroolsRuleLog drlLog, String type) {
        List<String> trackList = new ArrayList<String>();
        List<Map<String, Object>> list = drlLog.getLogs();
        for (Map<String, Object> map : list) {
            if (map.get("name") == null || StringUtils.isBlank(map.get("name").toString()))
                continue;
            if("RF".equals(type)) {
            	trackList.add(map.get("group").toString());
            }else {
            	String[] tempStrings = (map.get("name").toString()).split("_");
            	trackList.add(tempStrings[tempStrings.length - 1]);
            }
            System.out.println(map.get("group") + ":" + map.get("name"));
        }

        return trackList;
    }

    public Map<String,List> getTrailMap(DroolsRuleLog drlLog) {
        Map<String,List> trailMap = new HashMap<String,List>();
        List<Map<String, Object>> list = drlLog.getLogs();
        for (Map<String, Object> map : list) {
            if (map.get("name") == null || StringUtils.isBlank(map.get("name").toString()))
                continue;
            String key = map.get("group").toString();
            List<String> trailList = trailMap.get(key);
            if(trailList==null) {
            	trailList = new ArrayList<String>();
            	trailMap.put(key, trailList);
            }
            if(key.indexOf("RF")>-1) {
            	trailList.add(key);
            }else if(map.containsKey("track")) {
            	trailList.add((String)map.get("track"));
            }else {
            	String[] tempStrings = (map.get("name").toString()).split("_");
            	trailList.add(tempStrings[tempStrings.length - 1]);
            }
            System.out.println(map.get("group") + ":" + map.get("name"));
        }

        return trailMap;
    }
    /**
     * @param projectCode 项目代码
     * @param code        规则代码
     * @param version     版本
     * @return
     * @exception Exception
     */
    @Override
    public String showRuleDrl(String projectCode, String code, String version) throws Exception {
        String drl = null;
        Map<String, Object> map = new HashMap();
        map.put("projectCode", projectCode);
        map.put("code", code);
        map.put("version", version);

        List<RuleVersioninfo> versionInfoList = ruleVersioninfoService.findVersionList(map);
        if (versionInfoList != null && versionInfoList.size() > 0) {
            drl = versionInfoList.get(0).getRuleContent();
        }
        return drl;
    }

    /**
     * @param projectCode 项目代码
     * @param version     版本
     * @param manageId    项目id
     * @return
     * @exception Exception
     */
	@Override
	public String selectChallengerInfo(String version, String projectCode, String manageId) throws BizException {
		String challengerInfo = null;
		Map<String, Object> map = new HashMap();
        map.put("projectCode", projectCode);
        map.put("version", version);
        map.put("manageId", manageId);
        List<RuleVersioninfo> versionInfoList = ruleVersioninfoService.findChallengerInfo(map);
        String param = versionInfoList.get(0).getChampionChallengerInfo();
		return param;
	}

}


